package com.lening.gateway.handler;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import com.lening.gateway.web.Result;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ToDo:
 * @Author：牛强
 * @date: 2024/6/11 17:20
 */
@Slf4j
public class BodyRewriteFunction implements RewriteFunction<byte[], byte[]> {
    // 以确保线程安全，并防止在程序运行中意外修改列表
    private static final List<String> success = new ArrayList<String>();

    //给success集合赋值
    static {
        success.add("ok");
        success.add("成功");
        success.add("OK");
    }
    //判断resultData是否为汉字，如为汉字则加上引号
    public  boolean isStringAllChinese(String resultData) {
        // 汉字的Unicode范围是\u4e00-\u9fa5
        String regex = "^[\u4e00-\u9fa5]+$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(resultData);
        return matcher.matches();
    }

    @Override
    public Publisher<byte[]> apply(ServerWebExchange exchange, byte[] bytes) {

        ServerHttpResponse response = exchange.getResponse();

        String resultData = new String(bytes, StandardCharsets.UTF_8);

        log.info("resultData:{}", resultData);
        if(isStringAllChinese(resultData)){
            resultData='"'+resultData+'"';
        }


        //如果响应结果为空则直接返回成功
        if (bytes == null || bytes.length == 0) {
            return Mono.just(JSONUtil.toJsonStr(Result.ok()).getBytes());
        }

        //long 转 String
        //判断是否是json格式
        if (isJson(resultData)) {
            //判断第一个字符是不是"["
            if (resultData.startsWith("[")) {
                // 将JSON数组字符串转换为JSONArray对象
                JSONArray jsonArray = JSONUtil.parseArray(resultData);
                resultData =rewriteJsonArray(jsonArray);
            } else {
                //判断第一个字符是不是"{"
                // 将JSON对象字符串转换为JSONObject对象
                JSONObject object = JSONUtil.parseObj(resultData);
                resultData = rewriteJsonObject(object);
            }
        //如果响应结果是Result类型则直接返回
        if (isResultObj(resultData)) {
            return Mono.just(resultData.getBytes());
        }
        }

        //如果响应结果不是json类型并且有值并且不包含成功关键字则返回失败
        if (!isJson(resultData) && StringUtils.hasText(resultData) && success.stream().noneMatch(resultData::contains)&&!resultData.contains("<form")) {
            resultData = "{\"success\":false,\"code\":500,\"data\":null,\"message\":"+resultData+"}";
            return Mono.just(resultData.getBytes());
        }else if(resultData.startsWith("<")){
            resultData = "{\"success\":true,\"code\":200,\"data\":"+resultData+",\"message\":null}";
            return Mono.just(resultData.getBytes());
        }else {

            //否则返回成功
//            resultData = "{\"success\":true,\"code\":200,\"data\":\""+resultData+"\",\"message\":null}";
            resultData = "{\"success\":true,\"code\":200,\"data\":"+resultData+",\"message\":null}";
            log.info("resultData:{}",resultData);
            return Mono.just(resultData.getBytes());
        }
    }



    // 递归处理JSON对象或数组中的Long类型值，将其转换为字符串
//    public static void circle(Object obj) {
//
//        if (Objects.nonNull(obj) && isJson(obj.toString())) {
//            if (obj instanceof JSONObject) {
//                JSONObject jsonObject = (JSONObject) obj;
//                for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
//                    if (entry.getValue() instanceof Long) {
//                        entry.setValue(entry.getValue().toString());
//                    }
//                    //递归调用处理嵌套结构
//                    circle(entry.getValue());
//                }
//            } else if (obj instanceof JSONArray) {
//                JSONArray jsonArray = (JSONArray) obj;
//                for (Object item : jsonArray) {
//                    //处理嵌套结构
//                    circle(item);
//                }
//            }
//        }
//    }

    //创建一个方法传入的一个json对象，判断对象的属性值是否为Long类型，将原始的Long值转换为字符串后重新设置为属性值

    /**
     * 递归遍历JSON对象，将Long类型的值转换为字符串
     * @param jsonObject
     */
    public static String rewriteJsonObject(JSONObject jsonObject) {
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            Object value = entry.getValue();
            if (value instanceof Long) {
                entry.setValue(value.toString());
            } else if (value instanceof JSONObject) {
                rewriteJsonObject((JSONObject) value);
            } else if (value instanceof JSONArray) {
                rewriteJsonArray((JSONArray) value);
            }
        }
        return jsonObject.toString();

    }

    /**
     * 递归遍历JSON数组，将Long类型的值转换为字符串
     * @param jsonArray
     */
    public static String rewriteJsonArray(JSONArray jsonArray) {
        for (Object obj : jsonArray) {
            if (obj instanceof JSONObject) {
                rewriteJsonObject((JSONObject) obj);
            } else if (obj instanceof JSONArray) {
                rewriteJsonArray((JSONArray) obj);
            }
        }
        return jsonArray.toString();
    }


    /**
     * 检查给定的字符串是否为有效的JSON格式。
     * 通过正则表达式匹配来判断字符串是否为JSON对象或JSON数组。
     *
     * @param jsonString 待检查的字符串
     * @return 如果字符串是有效的JSON格式，则返回true；否则返回false。
     */
    public static boolean isJson(String jsonString) {
        /* 定义正则表达式，用于匹配JSON对象和JSON数组 */
        String pattern = "(\\{.*\\}|\\[.*\\])";
        /* 使用matches方法，检查字符串是否匹配正则表达式 */
        return jsonString.matches(pattern);
    }


    /**
     * 判断传入的字符串是否符合特定的JSON格式。
     * 此方法用于验证字符串是否是符合特定结构的结果对象的JSON表示，
     * 其中包含success、code、data和message四个字段。
     *
     * @param jsonString 待验证的JSON字符串。
     * @return 如果字符串符合预定义的JSON模式，则返回true；否则返回false。
     */
    public static boolean isResultObj(String jsonString) {
        /* 定义正则表达式模式，用于匹配JSON字符串。 */
        /* 此模式匹配包含"success"、"code"、"data"和"message"字段的JSON对象， */
        /* 其中"success"字段的值必须是true或false。 */
        String pattern = "\\{\"success\":(true|false),\"code\":.*,\"data\":.*,\"message\":.*\\}";
        /* 使用matches方法验证字符串是否符合正则表达式定义的模式。 */
        return jsonString.matches(pattern);
    }

}
